package com.chen.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chen.common.Result;
import com.chen.entity.Demo;
import com.chen.entity.Question;
import com.chen.entity.test.Grade;
import com.chen.entity.test.Student;
import com.chen.mapper.QuestionMapper;
import com.chen.service.impl.QuestionServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.Pair;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author chenchao
 * @date 2022/9/6 21:26
 */
@RestController
@RequestMapping(value = "/demo")
@Api(value = "DemoController", tags = "mongodb测试")
@SuppressWarnings("all")
public class DemoController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private QuestionServiceImpl questionService;


    @PostMapping(value = "/save")
    @ApiOperation(value = "保存")
    public List<Demo> saveDemo() {

        List<Demo> all = mongoTemplate.findAll(Demo.class);
        return all;
    }

    @GetMapping("/selectByContidition")
    @ApiOperation(value = "条件查询")
    public List<Demo> selectByContidition() {
        Query query = new Query();
        query.addCriteria(Criteria.where("age").gte(20).lte(34));
        List<Demo> demos = mongoTemplate.find(query, Demo.class);
        return demos;
    }

    @GetMapping("/selectByAccurate")
    @ApiOperation(value = "精确查询")
    public Result selectByAccurate() {
//        排序、查询总数
//        long count = mongoTemplate.count(new Query().with(Sort.by(Sort.Direction.DESC, "age")), Demo.class);
//      ================================================================================
//        根据id进行查询
//        Demo byId = mongoTemplate.findById("63175b8626e8555cea7cb4c1", Demo.class);
//      ===============================================================================
//        模糊查询
//        Query query=new Query();
//        Criteria criteria = Criteria.where("name").regex("张").and("salary").is(100000).and("age").gte(20);
//        query.addCriteria(criteria);
//        List<Demo> demos = mongoTemplate.find(query, Demo.class);
//      =============================================================================
//        修改
//        try {
//            Query query = new Query(Criteria.where("id").is("63175b8626e8555cea7cb4c1"));
//            Update update = new Update();
//            update.set("name","李四");
//            update.set("age",18);
//            UpdateResult updateResult = mongoTemplate.upsert(query, update, Demo.class);
//            long modifiedCount = updateResult.getModifiedCount();
//            if (modifiedCount>0){
//                return Result.success("更新成功");
//            }
//            throw new ServiceException(401,"更新失败");
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        =================================================================================
//        删除
//        try {
//            Query query = new Query(Criteria.where("id").is("63175b8626e8555cea7cb4c1"));
//            DeleteResult result = mongoTemplate.remove(query, Demo.class);
//            long deletedCount = result.getDeletedCount();
//            if(deletedCount>0){
//                return Result.success("删除成功");
//            }
//            throw new ServiceException(-1, String.format("【%s】%s", "63175b8626e8555cea7cb4c1", "不存在"));
//        } catch (ServiceException e) {
//            throw new RuntimeException(e);
//        }
//       ==================================================================================
//        新增
//        Demo demo = new Demo();
//        demo.setBirthday(new Date());
//        demo.setAge(22);
//        demo.setAddress("苏州");
//        demo.setSalary(100000);
//        Demo insert = mongoTemplate.insert(demo);
//        ================================================================================
//       分页
//        Criteria criteria = new Criteria();
//        criteria.andOperator(Criteria.where("name").regex("张"), Criteria.where("age").gte(18));
//        Query query = new Query(criteria);
//        query.with(Sort.by(Sort.Order.desc("age"))).skip(1).limit(3);
//        List<Demo> demos = mongoTemplate.find(query, Demo.class);
//        ================================================================================
//
        return Result.success();
    }

    /**
     * MongoDB分页
     *
     * @param pageNum
     * @param pageSize
     * @param name
     * @param address
     * @return
     */
    public Page<Demo> findDemoPage(int pageNum, int pageSize, String name, String address) {
//        先进行排序
        Sort sort = Sort.by(Sort.Direction.DESC, "birthday");
        PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize, sort);
//        创建一个query对象
        Query query = new Query();
        Criteria name1 = Criteria.where("name").regex(name);
        Criteria address1 = Criteria.where("address").regex(address);
//        判断有没有值
        if (!"".equals(name)) {
            query.addCriteria(name1);
        }
        if (!"".equals(address)) {
            query.addCriteria(address1);
        }
        long count = mongoTemplate.count(query, Demo.class);
        List<Demo> demos = mongoTemplate.find(query.with(pageRequest), Demo.class);
        return new PageImpl(demos, pageRequest, count);

    }

    @GetMapping("/findDemoPage")
    @ApiOperation(value = "demo分页")
    public Result findDemoPage1(@RequestParam(defaultValue = "1") Integer pageNum,
                                @RequestParam(defaultValue = "3") Integer pageSize,
                                @RequestParam(defaultValue = "") String name,
                                @RequestParam(defaultValue = "") String address) {
        return Result.success(findDemoPage(pageNum, pageSize, name, address));
    }

    @GetMapping("/1111")
    public void insertData(){
        ArrayList<Student> students = new ArrayList<>();
        ArrayList<Grade> grades = new ArrayList<>();
        Student student = new Student(1,"张三","男",1);
        Student student1 = new Student(2,"李四","女",2);
        Student student2 = new Student(3,"姝姝","女",3);
        students.add(student);
        students.add(student1);
        students.add(student2);
        Grade grade = new Grade(1,"一班");
        Grade grade1 = new Grade(2,"二班");
        Grade grade2 = new Grade(3,"三班");
        grades.add(grade);
        grades.add(grade1);
        grades.add(grade2);
        List<Pair<Query, Update>> updateList = new ArrayList<>(grades.size());

        BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, Grade.class);

        students.forEach(data -> {
            //recId为文档索引
            Query query = new Query(new Criteria("id").is(data.getId()));
            Update update;
            Document doc = new Document();
            mongoTemplate.getConverter().write(data, doc);
            update = Update.fromDocument(new Document("$set", doc));
            Pair<Query, Update> updatePair = Pair.of(query, update);
            updateList.add(updatePair);
        });
        operations.upsert(updateList);
        //执行
        operations.execute();

    }

    @GetMapping("/selectPage")
    public Object findStudentAndGrade(){
        LookupOperation lookupOperation = LookupOperation.newLookup()
                .from("grade").localField("gradeId").
                foreignField("_id").as("GradeAndStu");
        Aggregation aggregation = Aggregation.newAggregation(lookupOperation);
        List<Map> mapList = mongoTemplate.aggregate(aggregation, "student", Map.class).getMappedResults();
        System.out.println(JSON.toJSONString(mapList));
        return mapList;
    }


    @ApiOperation(value = "MP高级用法")
    @GetMapping("/mpTest")
    public Result MPTest(){
        QueryWrapper<Question> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("id","name","time","answer").like("name","是")
                .groupBy("id").having("id>{0}",10).orderByDesc("time");
        List<Map<String, Object>> mapList = questionMapper.selectMaps(queryWrapper);
        List<Object> objects = questionMapper.selectObjs(queryWrapper);
//        ====================================查询====================================================
        LambdaQueryWrapper<Question> lambdaQuery = Wrappers.<Question>lambdaQuery();
        lambdaQuery.gt(Question::getId,10);
        questionService.getOne(lambdaQuery,false);
//        ==========================================更新==============================================
        questionService.lambdaUpdate()
                .eq(Question::getId,25)
                .set(Question::getDetail,"你是谁")
                .update();
//        ===========================================================================================

        return Result.success(mapList);
    }
    @ApiOperation(value = "MP高级用法1")
    @GetMapping("/mpTest01")
    public Result MPTest01(){
        QueryWrapper<Question> queryWrapper = new QueryWrapper<Question>();
        Question question = new Question();
        question.setName("张三");
        questionMapper.insert(question);
       /* queryWrapper.select("*," +
                "(select username from user where id=question.user_id)userName," +
                "(select name from course where id=question.course_id)courseName");
        queryWrapper.apply("date_format(time,'%Y-%m-%d %H:%i')={0}","2022-09-27 21:35")
                    .notInSql("id","select id from question where name like 'what%'");
        List<Question> list = questionService.list(queryWrapper);*/
//        =======================================================================================
        queryWrapper.likeRight("name","是").or(
                r->r.gt("id",10).isNotNull("detail")
        );
        List<Question> list = questionService.list(queryWrapper);
//        =======================================================================================
        UpdateWrapper<Question> updateQueryWrapper=new UpdateWrapper();
        updateQueryWrapper.set("detail","你是");
        updateQueryWrapper.eq("id",26);
        questionService.update(updateQueryWrapper);
        return Result.success(list);
    }
}
